package com.lry.jvm.instructions.refrences;

import com.lry.jvm.instructions.base.ClassInit;
import com.lry.jvm.instructions.base.Index16Instruction;
import com.lry.jvm.rtda.Frame;
import com.lry.jvm.rtda.JObject;
import com.lry.jvm.rtda.heap.ClassRef;
import com.lry.jvm.rtda.heap.JClass;
import com.lry.jvm.rtda.heap.RuntimeConstantPool;
import com.lry.jvm.util.Util;

/**
 * <clinit> 触发
 * new
 * getstatic
 * putstatic
 * invokestatic
 * 反射
 */
public class jnew extends Index16Instruction {

    @Override
    public byte getOpCode() {
        return (byte) 0xbb;
    }

    @Override
    public void execute(Frame frame) {
        RuntimeConstantPool rcp = frame.getMethod().getJClass().getConstantPool();
        ClassRef classRef = (ClassRef) rcp.getConstant(index);
        JClass jClass = classRef.resolvedClass();

        if(!jClass.isInitStarted()){
            frame.revertNextPc();
            ClassInit.initClass(frame.getThread(),jClass);
            return;
        }

        if (jClass.isInterface() || jClass.isAbstract()) {
            Util.panic("java.lang.InstantiationError");
        }
        JObject ref = new JObject(jClass);
        frame.getOperandStack().pushRef(ref);
    }

}
